﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using l1cs.server.model.Instance;
using MySql.Data.MySqlClient;
using System.Data;
using l1cs.server.model.skill;
using l1cs.server.utils;
using l1cs.server.datatables;

namespace l1cs.server.model
{
    public class DungeonRandom
    {
        private static Logger _log = Logger.getLogger( typeof( DungeonRandom ).FullName );

        private static DungeonRandom _instance = null;

        private static Dictionary<String, NewDungeonRandom> _dungeonMap = new Dictionary<String, NewDungeonRandom>();
        private static Random _random = new Random();

        public static DungeonRandom getInstance()
        {
            if ( _instance == null )
            {
                _instance = new DungeonRandom();
            }
            return _instance;
        }

        private DungeonRandom()
        {
            String sqlstr = "SELECT * FROM dungeon_random";
            using ( MySqlWrapper wrapper = new MySqlWrapper() )
            {
                foreach ( DataRow item in wrapper.GetDataTable( sqlstr ).Rows )
                {
                    int srcMapId = SqlUtils.toInt( item["src_mapid"] );
                    int srcX = SqlUtils.toInt( item["src_x"] );
                    int srcY = SqlUtils.toInt( item["src_y"] );
                    String key = new StringBuilder().Append( srcMapId ).Append( srcX ).Append( srcY ).ToString();
                    int[] newX = new int[5];
                    int[] newY = new int[5];
                    short[] newMapId = new short[5];
                    newX[0] = SqlUtils.toInt( item["new_x1"] );
                    newY[0] = SqlUtils.toInt( item["new_y1"] );
                    newMapId[0] = SqlUtils.toShort( item["new_mapid1"] );
                    newX[1] = SqlUtils.toInt( item["new_x2"] );
                    newY[1] = SqlUtils.toInt( item["new_y2"] );
                    newMapId[1] = SqlUtils.toShort( item["new_mapid2"] );
                    newX[2] = SqlUtils.toInt( item["new_x3"] );
                    newY[2] = SqlUtils.toInt( item["new_y3"] );
                    newMapId[2] = SqlUtils.toShort( item["new_mapid3"] );
                    newX[3] = SqlUtils.toInt( item["new_x4"] );
                    newY[3] = SqlUtils.toInt( item["new_y4"] );
                    newMapId[3] = SqlUtils.toShort( item["new_mapid4"] );
                    newX[4] = SqlUtils.toInt( item["new_x5"] );
                    newY[4] = SqlUtils.toInt( item["new_y5"] );
                    newMapId[4] = SqlUtils.toShort( item["new_mapid5"] );
                    int heading = SqlUtils.toInt( item["new_heading"] );
                    NewDungeonRandom newDungeonRandom = new NewDungeonRandom( newX, newY, newMapId, heading );
                    if ( _dungeonMap.ContainsKey( key ) )
                    {
                        _log.log( Level.WARNING, "同じキーのdungeonデータがあります。key=" + key );
                    }
                    _dungeonMap[key] = newDungeonRandom;
                }
            }
        }

        private class NewDungeonRandom
        {
            public int[] _newX = new int[5];
            public int[] _newY = new int[5];
            public short[] _newMapId = new short[5];
            public int _heading;

            public NewDungeonRandom( int[] newX, int[] newY, short[] newMapId, int heading )
            {
                for ( int i = 0; i < 5; i++ )
                {
                    _newX[i] = newX[i];
                    _newY[i] = newY[i];
                    _newMapId[i] = newMapId[i];
                }
                _heading = heading;
            }
        }

        public bool dg( int locX, int locY, int mapId, L1PcInstance pc )
        {
            String key = new StringBuilder().Append( mapId ).Append( locX )
                    .Append( locY ).ToString();
            if ( _dungeonMap.ContainsKey( key ) )
            {
                int rnd = _random.Next( 5 );
                NewDungeonRandom newDungeonRandom = _dungeonMap[key];
                short newMap = newDungeonRandom._newMapId[rnd];
                int newX = newDungeonRandom._newX[rnd];
                int newY = newDungeonRandom._newY[rnd];
                int heading = newDungeonRandom._heading;

                // 2秒間は無敵（アブソルートバリア状態）にする。
                pc.setSkillEffect( L1SkillId.ABSOLUTE_BARRIER, 2000 );
                pc.stopHpRegeneration();
                pc.stopMpRegeneration();
                pc.stopMpRegenerationByDoll();
                L1Teleport.teleport( pc, newX, newY, newMap, heading, true );
                return true;
            }
            return false;
        }
    }
}
